iT邦幫忙

2021 iThome 鐵人賽

DAY 8
0

起初我是學 1.7 版本 JAVA,那時以為 1.7 API 很好用,應該夠用。但到了職場上,發現 JDK 1.8 的使用似乎變主流,我自己去看發現變化很多,其中 lambda 方式變成是 JDK 1.8 重要的物件。以下列出了基本的函數式介面

public interface Function<T, R> {

      R apply(T t);

}

傳入 T 回傳 R

@FunctionalInterface
public interface BiFunction<T, U, R> {
      R apply(T t, U u);
}

傳入兩個參數 TU,回傳 R

@FunctionalInterface
public interface Consumer<T> {
  void accept(T t);
}

傳入 T 回傳 void


@FunctionalInterface
public interface BiConsumer<T, U> {
  void accept(T t, U u);
}

傳入 TU,回傳 void

@FunctionalInterface
public interface Predicate<T> {
  boolean test(T t);
}

傳入 T 回傳 boolean

@FunctionalInterface
public interface BiPredicate<T, U> {
    boolean test(T t, U u);
}

傳入 TU,回傳 boolean

@FunctionalInterface
public interface Supplier<T> {
    T get();
}

不接受參數,回傳 T

只不過在開發上目前比較常用的是 forEachmapfilteroptional 等。但通常要使用這些的方式都要先將資料轉成 stream 以下為範例

Array to stream

int[] array = {1,2,3,4,5};
Arrays.stream(array);

collection to stream

List<String> list = Arrays.asList("a", "b", "c", "d");
Arrays.stream(list);

forEach 範例

      Map<String, Integer> map = new HashMap<>();
      map.put("A", 1);
      map.put("B", 2);
      map.put("C", 3);

      // -> is lambda
      map.forEach((k, v) -> System.out.println("Key : " + k + ", Value : " + v));
      // output
      Key : A, Value : 1
      Key : B, Value : 2
      Key : C, Value : 3

map 範例

List<String> list = Arrays.asList("a", "b", "c");
// 透過 map 將所有字母都轉大寫,最後用 collect 方式在將結果封裝成 List 回傳
List<String> collect = list.stream().map(String::toUpperCase).collect(Collectors.toList());

filter 範例

// getById 是一個從 SQL 映射回來的資料,並從中獲取 ecu 這個 List,接著將 List 轉 stream 並使用 filter 進行過濾,過濾的結過只要回傳第一個結果(findFirst)
Optional<Ecu> ecu = getById.getEcus()
                .stream().filter(i -> i.getId().equals(ecuClassId)).findFirst();
// 這邊回傳了一個Optional使我們可以針對 null 這個值進行細節處理
// 如果有值我就做什麼
if (ecu.isPresent()) {
    // do something
    // 要取值透過 get()
    ecu.get();
}

Optional 範例

代表一個值存在或不存在。可以避免 NullPointer 異常。

  • Optional.of(T t)
    • 創建一個 Optional 實例
Optional<Employee> op = Optional.of(new Employee()); // of 參數不能為 null,較好發現 null 值在哪
Employee emp = op.get();
System.out.println(emp); // 輸出默認值
  • Optional.empty()
    • 創建一個空的 Optional 實例
    • get 不到值
  • Optional.ofNullable(T t)
    • 若 t 不為 null,創建 Optional 實例,否則創建空實例
    • get 不到值
  • isPresent()
    • 斷是否包含值
  • orElse(T t)
    • 如果調用物件包含值,返回該值,否則返回 t
  • orElseGet(Supplier s)
    • 如果調用物件包含值,返回該值,否則返回 s 獲取的值
  • map(Function f)
    • 如果有值對其處裡,並返回處裡後的 Optional,否則返回 Optional.empty()
  • flatMap(Function mapper)
    • 與 map 類似,要求返回值必須是 Optional

其它好用的 stream 用法

  • filter
    • 過濾某些元素
  • limit
    • 截斷
  • skip
    • 跳過元素
  • distinct
    • 去重
    • 透過 hashCode() 和 equals() 去除重覆元素
  • sorted()
    • 自然排序
  • sorted(Compareator com)
    • 制定排序
  • allMatch(Predicate p)
    • 檢查是否頗配所有元素
  • anyMatch(Predicate p)
    • 檢查是否至少匹配一個元素
  • noneMatch(Predicate p)
    • 檢查是否沒有匹配所有元素
  • findFirst()
    • 返回第一個元素
  • findAny()
    • 返回當前 stream 中的任意元素
  • count()
    • 返回 stream 中元素總個數
  • max
    • 返回 stream 中最大值
  • min
    • 返回 stream 中最小值

反正一堆東西可以玩,跟本學步完...


上一篇
第一個 Spring boot 應用程式開發
下一篇
談談 Spring boot Controller API 怎麼設計
系列文
一個新鮮人如何完轉Spring boot與DevOps從0到10130
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言